package com.xcdh.commons.controller;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xcdh.commons.annotation.XCDHAspect;
import com.xcdh.commons.model.PrimaryId;
import com.xcdh.commons.query.QueryPayload;
import com.xcdh.commons.utils.exception.AssertUtil;
import com.xcdh.domain.RequestPage;
import com.xcdh.commons.spring.aspect.XCDHHTTPRequestLog;
import com.xcdh.domain.vo.PageVO;
import com.xcdh.domain.vo.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;

@Slf4j
public class BaseController<T,S extends IService<T>> {

    protected S baseService;

    public IService<T> getService() {
        return this.baseService;
    }
    protected ResolvableType getResolvableType() {
        return ResolvableType.forClass(ClassUtils.getUserClass(this.getClass()));
    }
    protected Class<T> currentModelClass() {
        return (Class)this.getResolvableType().as(BaseController.class).getGeneric(new int[]{0}).getType();
    }
    @Autowired
    public void setService(S baseService){
        log.info("service====={}",baseService);
        this.baseService = baseService ;
    }

    /**====================新增=======================**/
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/save")
    public  R<T> save(@RequestBody T data){
        this.getService().save(data);
        return R.okData(data) ;
    }
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/saveOrUpdate")
    public R<T> saveOrUpdate(@RequestBody T data){
        this.getService().saveOrUpdate(data);
        return R.okData(data) ;
    }

    @PostMapping("/saveBatch")
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    public R<Void> saveBatch(@RequestBody List<T> data){
        return R.result(this.getService().saveBatch(data)) ;
    }

    /**====================修改==============================**/
    @PostMapping("/update")
    @XCDHAspect(value= XCDHHTTPRequestLog.class)
    public R<T> update(@RequestBody T data){
        this.getService().updateById(data);
        return R.okData(data) ;
    }
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/updateBatch")
    public R<Void> updateBatch(List<T> data){
        boolean state = this.getService().updateBatchById(data);
        return R.result(state) ;
    }

    /**======================查询=======================**/
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/listByPage")
    public R<PageVO<T>> listByPage(@RequestBody RequestPage<T> page){
        IPage<T> result = this.getService().page(page, page.getQuery());
        return R.page(result);
    }

    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/list")
    public R<List<T>> list(@RequestBody T data){
        Wrapper<T> queryWrapper = new QueryWrapper<>(data);
        List<T> list = this.getService().list(queryWrapper);
        return R.okData(list);
    }

    @GetMapping("/{id}")
    public R<T> getById(@PathVariable Long id){
        return R.okData( this.getService().getById(id));
    }


    /**======================删除=======================**/
    @PostMapping("/deleteByIds")
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    public R<Void> deleteByIds(@RequestBody List<? extends Serializable> ids){
        return R.result(this.getService().removeByIds(ids)) ;
    }

    @DeleteMapping("/{id}")
    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    public R<Void> deleteById(@PathVariable Long id){
        return R.result(this.getService().removeById(id)) ;
    }

    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/v2/listByPage")
    public R<PageVO<T>> listByPage(@RequestBody QueryPayload queryPayload){
        Class<T> tClass = currentModelClass();
        IPage<T> result = this.getService()
                .page(queryPayload.getPageDto(tClass), queryPayload.getQueryWrapper(tClass));
        return R.page(result);
    }

    @XCDHAspect(value=XCDHHTTPRequestLog.class)
    @PostMapping("/v2/list")
    public R<List<T>> list(@RequestBody QueryPayload queryPayload){
        Class<T> tClass = currentModelClass();
        List<T> result = this.getService()
                .list(queryPayload.getQueryWrapper(tClass));
        return R.okData(result);
    }
}
